﻿using Mapster;
using Microsoft.AspNetCore.Mvc;
using RuoVea.OmiApp.Template.Dto;
using RuoVea.OmiApp.Template.Language;
using RuoVea.ExDto;
using RuoVea.ExEnum;
using RuoVea.ExSugar;
using RuoVea.ExUtil;
using RuoVea.OmiApp.Template.Entitys;

namespace RuoVea.OmiApp.Template.Service;

/// <summary>
/// 字典类型
/// </summary>
public class SysDictTypService : ISysDictTypService
{
    /// <summary>
    /// 
    /// </summary>
    public readonly SugarRepository<SysDictType> _thisRepository;
    private readonly ISysDictValueService _sysDictValueService;
    private readonly ICurrentUser _currentUser;
    /// <summary>
    /// 参数配置表
    /// </summary>
    /// <param name="thisRepository"></param>
    /// <param name="sysDictValueService"></param>
    /// <param name="currentUser"></param>

    public SysDictTypService(SugarRepository<SysDictType> thisRepository, ISysDictValueService sysDictValueService, ICurrentUser currentUser)
    {
        _thisRepository = thisRepository;
        _sysDictValueService = sysDictValueService;
        _currentUser = currentUser;
    }

    /// <summary>
    /// 查询所有/分页
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult<PageResult<SysDictTypeDto>>> GetPagesAsync(SysDictTypeParam data)
    {
        var restful = new RestfulResult<PageResult<SysDictTypeDto>>() { Code = CodeStatus.OK };
        bool supperAdmin = _currentUser.IsSuperAdmin;
        var code = !string.IsNullOrEmpty(data.Code?.Trim());
        var name = !string.IsNullOrEmpty(data.Name?.Trim());

        var query = await _thisRepository.AsQueryable()
            .Where(u => u.IsDelete == IsDelete.N && !supperAdmin || supperAdmin)
            .WhereIF(code, u => u.Code.Contains(data.Code!))
            .WhereIF(name, u => u.Name.Contains(data.Name!))
            .OrderBy(u => u.Sort)
            .ToPageAsync<SysDictType, SysDictTypeDto>(data.PageNo, data.PageSize);

        restful.Data = query;
        return restful;
    }

    /// <summary>
    /// 根据主键查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<RestfulResult<SysDictTypeDto>> GetDataAsync(long id)
    {
        var restful = new RestfulResult<SysDictTypeDto>() { Code = CodeStatus.BadRequest };
        if (id == 0)
        {
            restful.Message = i18n.getfail;
            return restful;
        }
        var model = await _thisRepository.AsQueryable().Where(x => x.Id == id).FirstAsync();
        restful.Data = model.Adapt<SysDictTypeDto>();
        return restful;
    }



    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> AddDataAsync(SysDictTypeDto data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };
        var isExist = await _thisRepository.IsAnyAsync(u => u.Name == data.Name || u.Code == data.Code);
        if (isExist)
        {
            restful.Message = ErrorEnum.D3001.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }
        var dictType = data.Adapt<SysDictType>();
        bool result = await _thisRepository.InsertAsync(dictType);
        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.addsuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.addfail;
            return restful;
        }
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> UpdateDataAsync(SysDictTypeDto data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };
        var isExist = await _thisRepository.IsAnyAsync(u => u.Id == data.Id);
        if (!isExist)
        {
            restful.Message = ErrorEnum.D3000.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        // 排除自己并且判断与其他是否相同
        isExist = await _thisRepository.IsAnyAsync(u => (u.Name == data.Name || u.Code == data.Code) && u.Id != data.Id);
        if (isExist)
        {
            restful.Message = ErrorEnum.D3001.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        var dictType = data.Adapt<SysDictType>();
        bool result = await _thisRepository.UpdateAsync(dictType);
        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.modifysuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.modifyfail;
            return restful;
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task<RestfulResult> DeleteDataAsync(long id)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        if (id == 0)
        {
            restful.Message = i18n.deletefail;
            return restful;
        }
        var dictType = await _thisRepository.GetFirstAsync(u => u.Id == id);
        if (dictType == null)
        {
            restful.Message = ErrorEnum.D3000.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        bool isDelete = false;

        if (dictType!.IsDelete == IsDelete.Y)
            isDelete = await _thisRepository.DeleteByIdAsync(id);
        else
        {
            dictType.IsDelete = IsDelete.Y;
            isDelete = await _thisRepository.UpdateAsync(dictType);
        }
        if (isDelete)
        {
            restful.Message = i18n.deletesuccess;
            restful.Code = CodeStatus.OK; return restful;
        }
        else
        {
            restful.Message = i18n.deletefail;
            return restful;
        }
    }

    /// <summary>
    /// 获取字典类型下所有字典值
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult<List<SysDictValue>>> GetDictTypeDropDown(DropDownDictTypeInput data)
    {
        RestfulResult<List<SysDictValue>> restful = new() { Code = CodeStatus.OK };
        var dictType = await _thisRepository.GetFirstAsync(u => u.Code == data.Code && u.IsDelete == IsDelete.N && u.Status == StatusEnum.ENABLE);
        if (dictType == null)
        {
            restful.Message = ErrorEnum.D3000.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        restful.Data = await _sysDictValueService.GetDictValueListByDictTypeId(dictType!.Id);
        return restful;
    }

    /// <summary>
    /// 更新字典类型状态
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> ChangeDictTypeStatus(ChangeStateDictTypeInput data)
    {
        RestfulResult restful = new() { Code = CodeStatus.OK };
        var dictType = await _thisRepository.GetFirstAsync(u => u.Id == data.Id && u.IsDelete == IsDelete.N);
        if (dictType == null)
        {
            restful.Message = ErrorEnum.D3000.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        if (!data.Status.IsDefined<StatusEnum>())
        {
            restful.Message = ErrorEnum.D3005.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        dictType!.Status = data.Status;
        dictType.IsDelete = IsDelete.N;
        bool result = await _thisRepository.UpdateAsync(dictType);

        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.modifysuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.modifyfail;
            return restful;
        }
    }


    #region NonAction
    /// <summary>
    /// 获取系统参数配置列表
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<List<SysDictType>> GetDataList()
    {
        return await _thisRepository.GetListAsync(u => u.IsDelete == IsDelete.N);
    }
    #endregion

    ///// <summary>
    ///// 字典类型与字典值构造的字典树
    ///// </summary>
    ///// <returns></returns>
    //[AllowAnonymous]
    //public async Task<List<DictTreeOutput>> GetDictTree()
    //{
    //    return await _thisRepository.AsQueryable().Where(x=>x.Deleted== IsDelete.N).Select(u => new DictTreeOutput
    //    {
    //        Id = u.Id,
    //        Code = u.Code,
    //        Name = u.Name,
    //        Children = _thisRepository..Select(c => new DictTreeOutput
    //        {
    //            Id = c.Id,
    //            Pid = c.TypeId,
    //            Code = c.Code,
    //            Name = c.Value
    //        }).ToList()
    //    }).ToListAsync();
    //}
}
